﻿; (function (global) {

    'use strict';

    global.Generator = function Generator() {

    }

    Generator.prototype.createNew = function (level) {
        var seedGrid = GridModel.fromShortString("---------------------------------------------------------------------------------");
        new BackTrakingSolver({ shuffle: true, allSolutions: false }).solve(seedGrid);

        var grid = this._createMaskedgrid(seedGrid, level);
        this._setCellsAsBase(grid);
        return grid;
    }

    Generator.prototype._createMaskedgrid = function (seedGrid, level) {
        var solver = new Solver(level.getAllowedStrategies());

        var tri = 0;
        do {
            var workingGrid = ObjectSerializer.duplicate(seedGrid);
            var workingCells = [];
            for (var i = 0; i < 81; i++) {
                var indices = IndicesHelper.getIndicesFromRank(i);
                workingCells.push(workingGrid.getCell(indices));
            }
            workingCells.shuffle();

            var emptyIndices = [];
            var okCount = 0;
            var effectiveStrats = [];
            while (workingCells.length > 0) {
                var cell = workingCells.pop();
                var valueBackup = cell.value;
                cell.setValue(0);

                var solveResult = solver.solve(workingGrid);
                if (solveResult.solved) {
                    emptyIndices.push(cell.indices);
                    effectiveStrats.pushArray(solveResult.performedResults);
                    okCount++;
                }
                else {
                    cell.setValue(valueBackup);
                }

                this._setCellsAsEmpty(workingGrid, emptyIndices);
                if (level.hasEnoughEmpty(emptyIndices.length))
                    break;
            }

        } while (!level.checkRequiredStrategies(effectiveStrats.map(function (elm) { return elm.strategy; })));
        return workingGrid;
    }

    Generator.prototype._setCellsAsEmpty = function (workingGrid, emptyIndices) {
        for (var i = 0; i < emptyIndices.length; i++) {
            var cell = workingGrid.getCell(emptyIndices[i]);
            cell.setValue(0);
        }
    }

    Generator.prototype._setCellsAsBase = function (finalGrid) {
        for (var i = 0; i < 9; i++) {
            for (var j = 0; j < 9; j++) {
                var cell = finalGrid.cells[i][j];
                cell.isBase = cell.value !== 0;
                cell.candidates.clear();
            }
        }
    }
}(this));
